package com.example.computer_exam_training_sys.controller;

import com.example.computer_exam_training_sys.entity.Question;
import com.example.computer_exam_training_sys.service.QuestionService;
import com.example.computer_exam_training_sys.service.KnowledgePointService;
import com.example.computer_exam_training_sys.entity.KnowledgePointInfo;
import com.example.computer_exam_training_sys.service.QuestionGenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.SocketTimeoutException;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

@RestController
@RequestMapping("/api/question")
@CrossOrigin
public class QuestionGenController {

    @Autowired
    private QuestionGenService questionGenService;
    @Autowired
    private QuestionService questionService;
    @Autowired
    private KnowledgePointService knowledgePointService;

    @PostMapping("/generate")
    public ResponseEntity<?> generate(@RequestBody Map<String, Object> payload) {
        try {
            Integer pointId = payload.get("pointId") != null ? Integer.parseInt(payload.get("pointId").toString()) : null;
            Integer courseId = payload.get("courseId") != null ? Integer.parseInt(payload.get("courseId").toString()) : null;
            String questionType = (String) payload.get("questionType");
            Integer difficulty = payload.get("difficulty") != null ? Integer.parseInt(payload.get("difficulty").toString()) : null;
            KnowledgePointInfo pointInfo = pointId != null ? knowledgePointService.findById(pointId) : null;
            String pointName = pointInfo != null ? pointInfo.getPointName() : "";
            
            // 1. 获取本知识点下所有题目
            List<Question> existed = pointId != null ? questionService.selectBypointId(pointId) : java.util.Collections.emptyList();
            // 1.1 查询全库所有题目，防止跨知识点重复
            List<Question> allQuestions = questionService.selectAll();
            
            // 2. 生成题目，查重，最多尝试5次
            int maxTry = 5;
            String aiResult = null;
            String lastContent = null;
            boolean isUnique = false;
            
            for (int i = 0; i < maxTry; i++) {
                // 构造prompt，加入难度区分
                StringBuilder sb = new StringBuilder();
                sb.append("请根据以下要求生成一道题目：\n");
                if (courseId != null) sb.append("课程ID:" + courseId + "\n");
                if (pointName != null && !pointName.isEmpty()) sb.append("知识点:" + pointName + "\n");
                if (questionType != null) sb.append("题型:" + questionType + "\n");
                if (difficulty != null) {
                    String diffStr = difficulty == 1 ? "简单" : (difficulty == 2 ? "中等" : "较难");
                    sb.append("难度:" + diffStr + "\n");
                }
                sb.append("题目内容（content）字段必须包含题干和所有选项，格式如：'题干\\nA. 选项A\\nB. 选项B\\nC. 选项C\\nD. 选项D'。\n请严格按照上述课程、知识点、题型、难度要求出题，严禁生成与要求不符的题目。\n\n【极其重要】请务必生成与本知识点下所有已有题目完全不同的新题目，题干、选项、答案、解析均不得与已有题目重复或高度相似。不得仅做微小改动、不得换序、不得仅替换数字或词语，必须是全新思路和表达。\n你可以结合互联网公开的历年真题、考试题库、典型案例等素材出题，但不得直接抄袭，必须重新组织语言和思路。若无法生成新题请直接返回\"无法生成不重复的新题目\"。\n请返回题干、答案、解析，格式为JSON对象，字段为content, answer, analysis。");
                String aiPrompt = sb.toString();
                aiResult = questionGenService.generateQuestion(aiPrompt);
                
                try {
                    com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
                    String jsonStr = aiResult.trim();
                    if (!jsonStr.startsWith("{")) {
                        int start = jsonStr.indexOf("{");
                        int end = jsonStr.lastIndexOf("}");
                        if (start >= 0 && end > start) {
                            jsonStr = jsonStr.substring(start, end + 1);
                        }
                    }
                    java.util.Map<String, Object> aiMap = mapper.readValue(jsonStr, java.util.Map.class);
                    String content = (String) aiMap.get("content");
                    lastContent = content;
                    
                    // 查重：与本知识点下所有题目content做相似度比对，同时与全库所有题目查重
                    boolean foundSimilar = false;
                    for (Question q : existed) {
                        if (q.getContent() != null && similarity(q.getContent(), content) > 0.85) {
                            foundSimilar = true;
                            break;
                        }
                    }
                    if (!foundSimilar) {
                        for (Question q : allQuestions) {
                            if (q.getContent() != null && similarity(q.getContent(), content) > 0.85) {
                                foundSimilar = true;
                                break;
                            }
                        }
                    }
                    if (!foundSimilar) {
                        // 唯一，入库
                        Question q = new Question();
                        q.setPointId(pointId);
                        q.setQuestionType(questionType);
                        q.setDifficulty(difficulty);
                        q.setContent(content);
                        
                        // 处理答案格式
                        String answer = (String) aiMap.get("answer");
                        String contentText = content;
                        Map<String, String> options = new HashMap<>();
                        
                        // 从content中提取选项
                        String[] lines = contentText.split("\n");
                        for (String line : lines) {
                            if (line.matches("^[A-D]\\..*")) {
                                String[] parts = line.split("\\.", 2);
                                if (parts.length == 2) {
                                    options.put(parts[0].trim(), parts[1].trim());
                                }
                            }
                        }
                        
                        // 构建新的答案格式，只包含correct和options
                        Map<String, Object> answerMap = new HashMap<>();
                        answerMap.put("correct", answer);
                        answerMap.put("options", options);
                        
                        q.setAnswer(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(answerMap));
                        q.setAnalysis((String) aiMap.get("analysis"));
                        q.setStatus(1);
                        int res = questionService.insert(q);
                        if (res > 0) {
                            return ResponseEntity.ok("生成并保存成功");
                        } else {
                            return ResponseEntity.ok("生成成功但保存失败");
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return ResponseEntity.ok("AI返回格式错误或保存失败: " + aiResult);
                }
            }
            return ResponseEntity.ok("多次生成均与已有题目重复或相似，最后一次内容：" + (lastContent != null ? lastContent : "无"));
        } catch (SocketTimeoutException e) {
            return ResponseEntity
                .status(HttpStatus.REQUEST_TIMEOUT)
                .body("AI服务响应超时，请稍后重试");
        } catch (Exception e) {
            return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("AI服务暂时不可用，请稍后重试");
        }
    }

    // 简单相似度算法：Jaccard相似度（可替换为更复杂算法）
    private double similarity(String a, String b) {
        if (a == null || b == null) return 0;
        java.util.Set<String> setA = new java.util.HashSet<>(java.util.Arrays.asList(a.replaceAll("[\n\r]", " ").split(" ")));
        java.util.Set<String> setB = new java.util.HashSet<>(java.util.Arrays.asList(b.replaceAll("[\n\r]", " ").split(" ")));
        java.util.Set<String> intersection = new java.util.HashSet<>(setA);
        intersection.retainAll(setB);
        java.util.Set<String> union = new java.util.HashSet<>(setA);
        union.addAll(setB);
        return union.size() == 0 ? 0 : (double) intersection.size() / union.size();
    }
}